<template>
  <div class="content">
    <Card>
      <Select
        v-model="selectedMonths"
        class="action-item"
        style="width:90px"
        size="small"
        placeholder="月份"
        :multiple="true"
        @on-change="handleSelectMonths">
        <Option v-for="item in monthList" :value="item.value" :key="item.value">{{ item.label }}</Option>
      </Select>
      <Select
        class="action-item"
        style="width:90px"
        size="small"
        placeholder="类别"
        :clearable="true"
        v-model="selectedCategory"
        @on-change="handleSelectCategory"
        @on-clear="handleClearCategory">
        <Option v-for="item in categories" :value="item.id" :key="item.id">{{ item.name }}</Option>
      </Select>
      <Button class="action-item" size="small" type="success" @click="handleCategoryAndSort">支出账单分类排序</Button>
      <Button class="action-item" size="small" type="primary" @click="showAddBillModal = true">添加账单</Button>
    </Card>
    <div class="bills">
      <p><strong>总收入：{{ $store.state.incomeAmount }} 元</strong></p>
      <p><strong>总支出：{{ $store.state.expendAmount }} 元</strong></p>
      <List item-layout="vertical">
        <ListItem v-for="(bill, index) in (isCategoryAndSort ? cBills : bills)" :key="index">
          <ListItemMeta :title="bill.category && bill.category.name" :description="bill.content" />
          <template slot="extra" v-if="!isCategoryAndSort">
            {{ bill.timeStr }}
          </template>
          <template slot="action" v-if="!isCategoryAndSort">
            <li>
              <a @click="handleDeleteBill(index)" style="color: #ff9900;">删除</a>
            </li>
          </template>
        </ListItem>
      </List>
    </div>

    <Modal
      v-model="showAddBillModal"
      title="添加账单"
      @on-ok="handleAddBill"
      @on-cancel="handleCancelAddBill"
      :closable="false"
      :mask-closable="false">
      <Form :model="bill" :label-width="80">
        <FormItem label="账单金额">
          <Input v-model="bill.amount" placeholder="请输入账单金额" />
        </FormItem>
        <FormItem label="账单分类">
          <Select v-model="bill.categoryId">
            <Option v-for="item in categories" :value="item.id" :key="item.id">{{ item.name }}</Option>
          </Select>
        </FormItem>
        <FormItem label="账单时间">
          <Row>
            <i-col span="11">
              <DatePicker type="date" placeholder="选择日期" v-model="bill.date"></DatePicker>
            </i-col>
            <i-col span="2" style="text-align: center">-</i-col>
            <i-col span="11">
              <TimePicker type="time" placeholder="选择时间" v-model="bill.timeStr"></TimePicker>
            </i-col>
          </Row>
        </FormItem>
      </Form>

      <div slot="footer">
        <Button type="primary" @click="handleAddBill">确认</Button>
        <Button style="margin-left: 8px" @click="handleCancelAddBill">取消</Button>
      </div>
    </Modal>
  </div>
</template>

<script>
import {
  calcIncomeAndExpendAmount,
  formatBills,
  getBills,
  getMonthList,
  getDateStr,
  getTimeInt
} from '@/assets/utils'
import axios from 'axios'
const d3 = require('d3-dsv')

export default {
  name: 'Home',
  data () {
    return {
      bills: [],
      categories: null,
      monthList: getMonthList(),
      selectedCategory: null,
      asc: true,
      selectedMonths: [],
      showAddBillModal: false,
      bill: {},
      isCategoryAndSort: false,
      cBills: []
    }
  },
  beforeMount () {
    this.initData()
  },
  methods: {
    initData () {
      this.bills = this.$store.state.bills
      this.categories = this.$store.state.categories
      if (this.bills && this.categories) {
        this.bills = formatBills(this.bills, this.categories)
        calcIncomeAndExpendAmount(this.$store, this.bills)
        return
      }

      axios.get('./categories.csv').then((res) => {
        this.categories = d3.csvParse(res.data)
        this.$store.commit('setCategories', {
          categories: this.categories
        })

        axios.get('./bills.csv').then((res) => {
          this.bills = d3.csvParse(res.data)
          this.$store.commit('setBills', {
            bills: this.bills
          })
          this.bills = formatBills(this.bills, this.categories)
          calcIncomeAndExpendAmount(this.$store, this.bills)
        }).catch((err) => {
          console.error(err)
          alert('账单数据初始化失败')
        })
      }).catch((err) => {
        console.error(err)
        alert('分类数据初始化失败')
      })
    },
    handleDeleteBill (index) {
      this.$Modal.confirm({
        title: '确定删除账单？',
        onOk: () => {
          const bills = getBills()
          bills.splice(index, 1)
          this.$store.commit('setBills', {
            bills: bills
          })
          this.bills.splice(index, 1)
          calcIncomeAndExpendAmount(this.$store, this.bills)
        },
        onCancel: () => {
          this.$Message.info('已取消删除账单')
        }
      })
    },
    handleSelectMonthsAndCategory () {
      this.isCategoryAndSort = false
      if (this.selectedMonths.length === 0 && !this.selectedCategory) {
        this.bills = this.$store.state.bills
      } else if (this.selectedMonths.length === 0 && this.selectedCategory) {
        this.bills = this.$store.state.bills.filter((bill) => {
          return this.selectedCategory === bill.category.id
        })
      } else if (this.selectedMonths.length !== 0 && !this.selectedCategory) {
        this.bills = this.$store.state.bills.filter((bill) => {
          return this.selectedMonths.indexOf(bill.month) !== -1
        })
      } else {
        this.bills = this.$store.state.bills.filter((bill) => {
          return this.selectedMonths.indexOf(bill.month) !== -1 && this.selectedCategory === bill.category.id
        })
      }
      calcIncomeAndExpendAmount(this.$store, this.bills)
    },
    handleSelectMonths (months) {
      this.handleSelectMonthsAndCategory()
    },
    handleSelectCategory (category) {
      this.handleSelectMonthsAndCategory()
    },
    handleClearCategory () {
      this.handleSelectMonthsAndCategory()
    },
    handleCategoryAndSort () {
      this.$Modal.confirm({
        title: '该操作会清除所选分类，是否执行？',
        onOk: () => {
          this.selectedCategory = null
          this.handleSelectMonthsAndCategory()
          this.$Message.warning('已清除所选分类！')
          this.isCategoryAndSort = true
          const cBills = {} // 所选月份的账单分类
          this.bills.forEach((bill) => {
            if (!cBills[bill.category.id]) {
              cBills[bill.category.id] = [bill]
            } else {
              cBills[bill.category.id].push(bill)
            }
          })
          const bills = []
          let bill
          const ck = Object.keys(cBills) // 已有账单类别列表
          ck.forEach((c) => {
            bill = null
            cBills[c].every((b) => {
              b = Object.assign({}, b)
              if (b.type === 1 || b.type === '1') { // 去除收入账单
                return false
              }
              if (bill) {
                bill.amount += b.amount
              } else {
                bill = b
              }
              return true
            })
            if (bill) {
              bill.content = (bill.type === 0 || bill.type === '0' ? '支出 ' : '收入 ') + bill.amount.toFixed(2) + ' 元'
              bills.push(bill)
            }
          })
          bills.sort((a, b) => {
            return a.amount - b.amount
          })
          this.cBills = bills
          calcIncomeAndExpendAmount(this.$store, bills)
          this.$Message.success('支出账单分类排序成功')
        },
        onCancel: () => {
          this.$Message.info('已取消分类排序操作')
        }
      })
    },
    handleAddBill () {
      const amount = parseFloat(this.bill.amount)
      if (!amount) {
        this.$Message.error('请输入正确的账号金额')
        return
      }
      if (!this.bill.categoryId) {
        this.$Message.error('请选择账单分类')
        return
      }
      if (!this.bill.date) {
        this.$Message.error('请设置账单日期')
        return
      }
      if (!this.bill.timeStr) {
        this.$Message.error('请设置账单具体时间')
        return
      }

      this.bill.amount = amount
      this.bill.category = this.categories.find((category) => {
        return category.id === this.bill.categoryId
      })
      this.bill.type = parseInt(this.bill.category.type)
      this.bill.timeStr = getDateStr(this.bill.date) + ' ' + this.bill.timeStr
      this.$store.dispatch('addBills', {
        bills: [
          {
            type: this.bill.type,
            category: this.bill.category.id,
            amount: this.bill.amount,
            time: getTimeInt(this.bill.timeStr)
          }
        ]
      })

      this.bills.splice(0, 0, {
        type: this.bill.type,
        category: this.bill.category,
        amount: this.bill.amount,
        timeStr: this.bill.timeStr,
        time: getTimeInt(this.bill.time),
        content: (this.bill.type === 0 || this.bill.type === '0' ? '支出 ' : '收入 ') + this.bill.amount.toFixed(2) + ' 元'
      })
      calcIncomeAndExpendAmount(this.$store, this.bills)
      this.bill = {}
      this.showAddBillModal = false
    },
    handleCancelAddBill () {
      this.bill = {}
      this.showAddBillModal = false
      this.$Message.info('已取消添加账单')
    }
  }
}
</script>

<style scoped lang="scss">
.bills {
  width: 400px;
  margin: 20px auto 0;
}
.content {
  width: 500px;
  margin: 20px auto 0;
}
.action-item {
  margin: 0 5px;
}
</style>
